package bma.common.langutil.concurrent;

import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 
 * @author guanzhong
 * @since 1.0 (imported from BMA.ESP Project)
 * 
 */
public class ExecutorPassive implements Executor, Wakeupable {

	final org.slf4j.Logger log = org.slf4j.LoggerFactory
			.getLogger(ExecutorPassive.class);

	protected ProcessQueue core;

	public ExecutorPassive(ProcessQueue p) {
		super();
		this.core = p;
	}

	public ExecutorPassive(String name) {
		super();
		this.core = new ProcessQueue(name);
	}

	public String getName() {
		return this.core.getName();
	}

	public ProcessQueue getCore() {
		return core;
	}

	public boolean start() {
		return this.core.initProcess();
	}

	public boolean run(long waitTime) {
		if (!core.isAlive()) {
			return false;
		}

		try {
			core.process(waitTime < 0 ? ProcessQueue.MAX_SLEEP_TIME : waitTime);
		} catch (Throwable e) {
			log.warn("run exception", e);
		}
		return true;
	}

	@Override
	public void execute(Runnable command) {
		if (!core.postIntent(command)) {
			throw new RejectedExecutionException("executor closed");
		}
	}

	public boolean isTerminated() {
		return !this.core.isAlive();
	}

	public void shutdown() {
		ProcessIntentClose closeIntent = new ProcessIntentClose();
		if (core.postIntent(closeIntent)) {
			if (log.isInfoEnabled()) {
				log.info("{}: shutdown", getName());
			}
		}
	}

	public boolean awaitTermination(long timeout, TimeUnit unit) {
		if (run(unit.toMillis(timeout))) {
			return false;
		}
		return true;
	}

	@Override
	public void wakup() {
		this.core.wakup();
	}
}
